<?php

class VideoService extends AbstractService
{

    /**
     * @var VideoService
     */
    private static $instance;

    /**
     * Get instance of VideoService.
     *
     * @return VideoService
     */
    public static function get()
    {
        if (!self::$instance) {
            self::$instance = new VideoService();
        }
        return self::$instance;
    }

    /**
     * Construction.
     */
    protected function __construct()
    {
        parent::__construct();
    }

    /**
     * 处理创建时的逻辑
     *
     * @param int $shardId
     * @return void
     */
    public function handleCreate($shardId)
    {

    }

    /**
     * 处理登录时的逻辑
     *
     * @param int $userId
     * @return void
     */
    public function handleLogin($userId)
    {

    }

    /**
     * 提供当前 service 数据
     *
     * @param int $userId
     * @param boolean $visitMode default false
     * @return array()
     */
    public function info($userId, $visitMode = false)
    {
        $videoList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_VIDEO);
        return array(
            $videoList
        );
    }

    /**
     * 领取观看视频奖励
     * @param $userId
     * @param $videoId
     * @param $reqTime
     * @return array
     * @throws SzException
     */
    public function getVideoRewards($userId, $videoId, $reqTime)
    {
        $videoSetting = SzConfig::get()->loadAppConfig(GameConst::CONFIG_VIDEO, $videoId, true);
        /**
         * @var VideoVo $video
         * @var VideoVo $_video
         * @var ModuleProfileInfoVo $profileInfo
         */
        $videoList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_VIDEO);
        //获取玩家平台数据
        $platformId = UserService::get()->getInfo($userId, GameConst::USER_INFO_TYPE_USER_PLATFORM);

        $reqDate = SzTime::getDate($reqTime);
        if ($videoSetting['sp_group'] == 1) {//如果是露天电影院
            $totalCount = 0;
            foreach ($videoList->getList() as $_videoId => $_video) {
                $_videoSetting = SzConfig::get()->loadAppConfig(GameConst::CONFIG_VIDEO, $_videoId, true);
                if ($_videoSetting['sp_group'] == 1 && SzTime::getDate($_video->getLastClaimTime()) == $reqDate) {
                    $totalCount += $_video->getClaimCount();
                }
            }
            $cinemaLimit = SzConfig::get()->loadAppConfig(ModuleProfileConst::CONFIG_PROFILE, 'cinemaLimit', true);
            $cinemaLimit = $cinemaLimit['value'];
            if ($totalCount >= $cinemaLimit) {
                throw new SzException(29152, array($totalCount, $cinemaLimit));
            }
        }
        $video = $videoList->getElement($videoId, false);
        if (!$video) {
            $video = new VideoVo($userId, $videoId, 1, $reqTime);
            $videoList->addElement($video);
            $videoList->setElement($videoId, $video);
        } else {
            $claimCount = $video->getClaimCount();
            $tempLimit = $videoSetting['sp_limit'];
            //打地鼠
            if ($videoId == 16001 && $platformId == 'tt'){
                $tempLimit = SzConfig::get()->loadAppConfig(ModuleProfileConst::CONFIG_PROFILE, 'TikTokGopherVideoTime', true)['value'];
            }
            //社团捐献
            if ($videoId == 18001 && $platformId == 'tt'){
                $tempLimit = SzConfig::get()->loadAppConfig(ModuleProfileConst::CONFIG_PROFILE, 'TikTokGuildVideoTime', true)['value'];
            }
            //抢夺花农
            if ($videoId == 19001 && $platformId == 'tt'){
                $tempLimit = SzConfig::get()->loadAppConfig(ModuleProfileConst::CONFIG_PROFILE, 'TikTokFloristVideoTime', true)['value'];
            }
            if (SzTime::getDate($video->getLastClaimTime()) != $reqDate) {
                $claimCount = 0;
            } else if ($claimCount >= $tempLimit) {
                throw new SzException(29151, array($videoId, $claimCount, $videoSetting['sp_limit']));
            }
            $video->setClaimCount(++$claimCount);
            $video->setLastClaimTime($reqTime);
            $videoList->updateElement($videoId, $video);
        }
        SzPersister::get()->setVoList($videoList);

        if (($videoId == 30004 ||  $videoId == 30002  ||  $videoId == 30003) && $platformId == 'tt') {
            $rewards = $this->getRewards($userId, $videoSetting);
        }else{
            $rewards = $this->getRewards($userId, $videoSetting);

            $tid = '';
            foreach ($rewards as $entityId => $count) {
                if ($entityId == 0) {
                    continue;
                }
                GameService::get()->handleEntity($userId, $entityId, $count, true, true);
                $tid .= $entityId . ":" . abs($count) . '|';
            }

        }


        if ($videoSetting['peraga']) {
            /**
             * @var $profileInfoList  ModuleProfileInfoVoList
             */
            $profileInfoList = SzPersister::get()->getVoList($userId, ModuleProfileConst::ORM_NAME_PROFILE_INFO);
            $guildId = GuildService::get()->getUserGuildId($userId,$profileInfoList);
            if (!$guildId) {
                return array(
                    'code' => GameConst::CODE_1005, // 未加入公会
                );
            }
            /**
             * @var GuildInfoVo $guildInfo
             */
            $guildInfo = SzPersister::get()->getVo(null, GameConst::ORM_NAME_GUILD_INFO, $guildId);
            if (!$guildInfo) {
                return array(
                    'code' => GameConst::CODE_9999 // 公会不存在
                );
            }
            /**
             * @var $guildMemberInfoList GuildMemberInfoVoList
             * @var $guildMemberInfo GuildMemberInfoVo
             */
            $guildMemberInfoList = SzPersister::get()->getVoList($guildId, GameConst::ORM_NAME_GUILD_MEMBER_INFO);
            $guildMemberInfo = $guildMemberInfoList->getElement($userId,false);
            if (!$guildMemberInfo) {
                return array(
                    'code' => GameConst::CODE_9999,
                );
            }

            $guildMemberInfo->updateMoney($videoSetting['peraga']);
            $guildMemberInfoList->updateElement($userId,$guildMemberInfo);
            SzPersister::get()->setVoList($guildMemberInfoList);

            $guildInfo->updateMoney($videoSetting['peraga']);
            SzPersister::get()->setVo($guildInfo);
        }
        if ($videoSetting['sp_group'] == 9) {
            $profileInfoList = SzPersister::get()->getVoList($userId, ModuleProfileConst::ORM_NAME_PROFILE_INFO);
            $profileInfo = $profileInfoList->getElement(GameConst::USER_INFO_TYPE_VIDEO_BUFF, false);
            if (!$profileInfo) {
                $profileInfo = new ModuleProfileInfoVo(
                    $userId,
                    GameConst::USER_INFO_TYPE_VIDEO_BUFF,
                    $reqTime,
                    $reqTime,
                    true
                );
                $profileInfoList->addElement($profileInfo);
                $profileInfoList->setElement(GameConst::USER_INFO_TYPE_VIDEO_BUFF, $profileInfo);
            }
            if ($platformId == 'tt'){
                $orderVideoCd = SzConfig::get()->loadAppConfig(ModuleProfileConst::CONFIG_PROFILE, 'TikTokIncomeVideoCd', true);
                $orderVideoCd = $orderVideoCd['value'];
                $expireTime = $orderVideoCd + $reqTime;
               // $expireTime = $reqTime;
            }else{
                $expireTime = $rewards[0] + $reqTime;
              //  $expireTime = $reqTime;
            }
            $profileInfo->setInfo((int)$expireTime);
            $profileInfo->setTime($reqTime);
            $profileInfoList->updateElement(GameConst::USER_INFO_TYPE_VIDEO_BUFF, $profileInfo);
            SzPersister::get()->setVoList($profileInfoList);
        }

        NewTaskService::get()->updateProgress($userId, GameConst::TASK_WATCH_VIDEO, 1);
        NewTaskService::get()->updateDailyTask($userId,GameConst::DAILY_TASK_VIDEO,1);

        // 数据采集：观看某模块弹出视频
        StatisticsService::get()->saveLog($userId, GameConst::LOG_TYPE_USER_ORBIT, array(
            'clientData' => array(
                'tid' => 'Module:video|action:watch|',
                'item' => $videoId,
                'value' => 1
            )
        ));

        if (!empty($tid)) {
            // 数据采集：观看视频产出
            StatisticsService::get()->saveLog($userId, GameConst::LOG_TYPE_RESOURCE_INPUT, array(
                'clientData' => array(
                    'tid' => $tid,
                    'item' => 'video_watch&' . $videoId
                )
            ));
        }

        if ($videoSetting['sp_group'] == 10) {
            // 更新合约任务进度
            $contractData = ContractService::get()->getContractOpenAndTask($userId,GameConst::CONTRACT_TASK_7,$reqTime);
            if (!empty($contractData) && !empty($contractData['task']) && !empty($contractData['session'])){
                if ($reqTime >= $contractData['start'] && $reqTime <= $contractData['end']){
                    ContractService::get()->updateTaskProgress($userId,$contractData['session'],$contractData['task']['pos'],$contractData['task']['taskId'],$reqTime);
                }
            }
        }

        return $rewards;
    }

    /**
     * 领取观看视频奖励(种植加速)
     * @param $userId
     * @param $videoId
     * @param $gridIds
     * @param $reqTime
     * @return array
     * @throws SzException
     */
    public function getVideoRewardsSpeedUp($userId, $videoId,$gridIds, $reqTime)
    {
        $isFree = 1;
        foreach ($gridIds as $gridId) {
            PlantService::get()->speedUp($userId, $gridId, $reqTime,$isFree);
        }

        NewTaskService::get()->updateProgress($userId, GameConst::TASK_WATCH_VIDEO, 1);
        NewTaskService::get()->updateDailyTask($userId,GameConst::DAILY_TASK_VIDEO,1);

        // 数据采集：观看某模块弹出视频
        StatisticsService::get()->saveLog($userId, GameConst::LOG_TYPE_USER_ORBIT, array(
            'clientData' => array(
                'tid' => 'Module:video|action:watch|',
                'item' => $videoId,
                'value' => 1
            )
        ));

    }

    /**
     * 获取视频奖励
     * @param $userId
     * @param $videoSetting
     * @return array
     */
    public function getRewards($userId, $videoSetting)
    {
        if ($videoSetting['sp_group'] != 6) {
            return $videoSetting['sp_reward'];
        }
        $items = SeedService::get()->getCultivateLackItems($userId);
        if (!count($items)) {
            $items = $videoSetting['sp_reward'];
        }
        if (!is_array($items) || !count($items)) {
            return [];
        }
        $key = array_rand($items);
        $entityId = EntityService::get()->buildEntityId(GameConst::ENTITY_ACTION_GET, GameConst::ENTITY_TYPE_ITEM, $items[$key]);
        return [$entityId => 1];
    }

    /**
     * @param $userId
     * @param $reqTime
     * @param $position
     * @return array
     * @throws SzException
     */
    public function getVideoOrder($userId, $reqTime, $position)
    {
        /**
         * @var OrderVoList $orderList
         * @var OrderVo $order
         */
        $orderList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_ORDER);

        $order = $orderList->getElement($position);
        if ($order->getOrderId() == 99999999 && $order->getCooldown() <= $reqTime) {
            $order->setStatus(1);
            $orderList->updateElement($position, $order);
            SzPersister::get()->setVoList($orderList);
            StatisticsService::get()->saveLog($userId, GameConst::LOG_TYPE_USER_ORBIT, array(
                'clientData' => array(
                    'tid' => 'Module:video_order|action:watch|',
                    'item' => $position,
                    'value' => 1
                )
            ));
        }
        NewTaskService::get()->updateProgress($userId, GameConst::TASK_WATCH_VIDEO, 1);
        NewTaskService::get()->updateDailyTask($userId,GameConst::DAILY_TASK_VIDEO,1);
        return $order->toArray();
    }

    /**
     * 获取状态
     * @param $userId
     * @param $videoId
     * @param $reqTime
     * @return bool
     * @throws SzException
     */
    public function getBuffStatus($userId, $videoId, $reqTime)
    {//20190529
        $hasVideoBuff = false;
        $hasSkipVideo = false;
        /**
         * @var ModuleProfileInfoVo $profileInfo
         * @var ModuleProfileInfoVo $profileVideoBuffInfo
         * @var ModuleProfileInfoVo $profileSkipVideoInfo
         */
        $profileInfoList = SzPersister::get()->getVoList($userId, ModuleProfileConst::ORM_NAME_PROFILE_INFO);
        $profileVideoBuffInfo = $profileInfoList->getElement(GameConst::USER_INFO_TYPE_VIDEO_BUFF, false);
        $profileSkipVideoInfo = $profileInfoList->getElement(GameConst::USER_INFO_TYPE_SKIP_VIDEO_CARD, false);
        if ($profileSkipVideoInfo) {
            $expireTime = (int)$profileSkipVideoInfo->getRawInfo();
            if ($expireTime >= $reqTime) {
                $hasSkipVideo = true;
//                return true;
            }
        }

        if ($profileVideoBuffInfo) {
            $expireTime = (int)$profileVideoBuffInfo->getRawInfo();
            if ($expireTime >= $reqTime) {
                $hasVideoBuff = true;
//                return true;
            }
        }
        if (!$hasVideoBuff && !$hasSkipVideo){
            return false;
        }
        else{
            return true;
        }

//        /**
//         * @var VideoVo $video
//         */
//        $reqDate = SzTime::getDate($reqTime);
//        $videoList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_VIDEO);
//        $video = $videoList->getElement($videoId, false);
//        if (!$video) {
//            return false;
//        }
//        if (SzTime::getDate($video->getLastClaimTime()) != $reqDate) {
//            return false;
//        }
//        return true;
    }

    public function getActivityJumpNum($userId, $reqTime) {
        /**
         * @var VideoVo $video
         */
        $reqDate = SzTime::getDate($reqTime);
        $videoList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_VIDEO);
        $video = $videoList->getElement(GameConst::VIDEO_ACTIVITY_JUMP, false);
        if (!$video) {
            return 0;
        }
        if (SzTime::getDate($video->getLastClaimTime()) != $reqDate) {
            return 0;
        }

        $videoSetting = SzConfig::get()->loadAppConfig(GameConst::CONFIG_VIDEO, GameConst::VIDEO_ACTIVITY_JUMP, true);

        return $video->getClaimCount() * $videoSetting['sp_reward'][0];
    }

    /**
     * 视频减少培育时间
     * @param $userId
     * @param $reqTime
     * @return mixed
     * @throws SzException
     */
    public function videoRefreshCultivateTime($userId,$reqTime) {
        NewCultivateService::get()->refreshCultivateHarvestTime($userId,$reqTime);
        $landId = 21030001; // 暂时固定值  后期修改
        /**
         * @var NewCultivateLandVoList $userLandList
         * @var NewCultivateLandVo $userLand
         */
        $userLandList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_NEW_CULTIVATE_LAND);
        $userLand = $userLandList->getElement($landId);

        $harvestTime = $userLand->getHarvestTime();
        if ($userLand->getVideoTime()) {
            return $harvestTime;
        }

        if ($reqTime >= $harvestTime) {
            return $harvestTime;
        }
        $userLand->setHarvestTime((int)($harvestTime - ($harvestTime - $reqTime) / 2));
        $userLand->setVideoTime(1);
        $userLandList->updateElement($landId,$userLand);
        SzPersister::get()->setVoList($userLandList);


        // 数据采集：观看某模块弹出视频
        StatisticsService::get()->saveLog($userId, GameConst::LOG_TYPE_USER_ORBIT, array(
            'clientData' => array(
                'tid' => 'Module:video|action:watch|',
                'item' => 13002,
                'value' => 1
            )
        ));

        NewTaskService::get()->updateProgress($userId, GameConst::TASK_WATCH_VIDEO, 1);
        NewTaskService::get()->updateDailyTask($userId,GameConst::DAILY_TASK_VIDEO,1);

        return $userLand->getHarvestTime();
    }
}
